home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / util / introspect.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  31KB  |  986 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. import sys
  6. import time
  7. import threading
  8. import string
  9. import logging
  10. import re
  11. import keyword
  12. import types
  13. import inspect
  14. import primitives
  15. from weakref import ref
  16. from types import GeneratorType
  17. from path import path
  18. from collections import defaultdict
  19. from traceback import print_exc
  20. import warnings
  21. log = logging.getLogger('util.introspect')
  22. oldvars = vars
  23.  
  24. def uncollectable(clz):
  25.     import gc as gc
  26.     gc.collect()
  27.     return _[1]
  28.  
  29.  
  30. class debug_property(object):
  31.     
  32.     def __init__(self, fget = None, fset = None, fdel = None, doc = None):
  33.         self._debug_property__get = fget
  34.         self._debug_property__set = fset
  35.         self._debug_property__del = fdel
  36.         self.__doc__ = doc
  37.  
  38.     
  39.     def __get__(self, inst, type = None):
  40.         if inst is None:
  41.             return self
  42.         
  43.         if self._debug_property__get is None:
  44.             raise AttributeError, 'unreadable attribute'
  45.         
  46.         
  47.         try:
  48.             return self._debug_property__get(inst)
  49.         except AttributeError:
  50.             e = None
  51.             print_exc()
  52.             raise AssertionError('attribute error during __get__')
  53.  
  54.  
  55.     
  56.     def __set__(self, inst, value):
  57.         if self._debug_property__set is None:
  58.             raise AttributeError, "can't set attribute"
  59.         
  60.         
  61.         try:
  62.             return self._debug_property__set(inst, value)
  63.         except AttributeError:
  64.             e = None
  65.             print_exc()
  66.             raise AssertionError('attribute error during __set__')
  67.  
  68.  
  69.     
  70.     def __delete__(self, inst):
  71.         if self._debug_property__del is None:
  72.             raise AttributeError, "can't delete attribute"
  73.         
  74.         
  75.         try:
  76.             return self._debug_property__del(inst)
  77.         except AttributeError:
  78.             e = None
  79.             print_exc()
  80.             raise AssertionErrror('attribute error during __del__')
  81.  
  82.  
  83.  
  84.  
  85. def vars(obj = None):
  86.     res = { }
  87.     if hasattr(obj, '__dict__'):
  88.         return oldvars(obj)
  89.     elif hasattr(obj, '__slots__'):
  90.         return (dict,)((lambda .0: for attr in .0:
  91. (attr, getattr(obj, attr, sentinel)))(obj.__slots__))
  92.     elif hasattr(obj, 'keys'):
  93.         return obj
  94.     else:
  95.         return dict((lambda .0: for x in .0:
  96. (x, sentinel))(obj))
  97.  
  98. version_23 = sys.version_info < (2, 4)
  99.  
  100. def this_list():
  101.     d = inspect.currentframe(1).f_locals
  102.     nestlevel = 1
  103.     while '_[%d]' % nestlevel in d:
  104.         nestlevel += 1
  105.     result = d['_[%d]' % (nestlevel - 1)]
  106.     if version_23:
  107.         return result.__self__
  108.     else:
  109.         return result
  110.  
  111.  
  112. def cannotcompile(f):
  113.     return f
  114.  
  115.  
  116. def stack_trace(level = 1, frame = None):
  117.     
  118.     try:
  119.         if frame is None:
  120.             f = sys._getframe(level)
  121.         else:
  122.             f = frame
  123.         frames = []
  124.         while f is not None:
  125.             c = f.f_code
  126.             frames.insert(0, (c.co_filename, c.co_firstlineno, c.co_name))
  127.             f = f.f_back
  128.         return frames
  129.     finally:
  130.         del f
  131.         del frame
  132.  
  133.  
  134.  
  135. def print_stack_trace(frame = None):
  136.     trace = stack_trace(2, frame)
  137.     for frame in trace:
  138.         print '  File "%s", line %d, in %s' % frame
  139.     
  140.  
  141.  
  142. def print_stack_traces():
  143.     frames = sys._current_frames().items()
  144.     for id, frame in frames:
  145.         print 'Frame %d:' % id
  146.         print_stack_trace(frame)
  147.     
  148.  
  149.  
  150. def is_all(seq, my_types = None):
  151.     if not seq:
  152.         
  153.         try:
  154.             iter(my_types)
  155.         except:
  156.             t = my_types
  157.         else:
  158.             t = my_types[0]
  159.         finally:
  160.             return (True, t)
  161.  
  162.     
  163.     if type(my_types) == type:
  164.         my_types = [
  165.             my_types]
  166.     
  167.     if my_types == None:
  168.         my_types = [
  169.             type(seq[0])]
  170.     
  171.     all = True
  172.     for elem in seq:
  173.         if type(elem) not in my_types:
  174.             all = False
  175.             break
  176.             continue
  177.     
  178.     if all:
  179.         return (all, my_types[0])
  180.     else:
  181.         return (all, None)
  182.  
  183.  
  184. def shift(l, varnames):
  185.     vars = varnames.split()
  186.     n = len(vars) - 1
  187.     l = l[:n] + [
  188.         l[n:]]
  189.     caller = sys._getframe().f_back
  190.     new_locals = dict(zip(vars, l))
  191.     for var, val in new_locals.items():
  192.         caller.f_locals[var] = val
  193.     
  194.     print caller.f_locals
  195.  
  196.  
  197. def get_func_name(level = 1):
  198.     return sys._getframe(level).f_code.co_name
  199.  
  200.  
  201. def get_func(obj, command, *params):
  202.     
  203.     try:
  204.         func = getattr(obj, command.lower())
  205.         log.debug('Finding %s.%s%s', obj.__class__.__name__, command.lower(), params)
  206.     except AttributeError:
  207.         obj.__class__.__name__(command.lower(), ', '.join, [], []([ repr(x) for x in params ]))
  208.         func = None
  209.     except:
  210.         '%s has no function to handle: %s(%s)'
  211.  
  212.     return func
  213.  
  214.  
  215. def decormethod(decorator):
  216.     
  217.     def wrapper(method):
  218.         return (lambda self: decorator(self, method, *args, **kw))
  219.  
  220.     return wrapper
  221.  
  222.  
  223. def funcToMethod(func, clas, method_name = None):
  224.     func.im_class = clas
  225.     func.im_func = func
  226.     func.im_self = None
  227.     if not method_name:
  228.         method_name = func.__name__
  229.     
  230.     clas.__dict__[method_name] = func
  231.  
  232.  
  233. def attach_method(obj, func, name = None):
  234.     if not name:
  235.         pass
  236.     name = func.__name__
  237.     cls = obj.__class__
  238.     cls.temp_foo = func
  239.     obj.__setattr__(name, cls.temp_foo)
  240.     del cls.temp_foo
  241.  
  242.  
  243. def isgeneratormethod(object):
  244.     return isinstance(getattr(object, '__self__', None), GeneratorType)
  245.  
  246. CO_VARARGS = 4
  247. CO_VARKEYWORDS = 8
  248.  
  249. def callany(func, *args):
  250.     if not callable(func):
  251.         raise TypeError, "callany's first argument must be callable"
  252.     
  253.     CallLater = CallLater
  254.     CallLaterDelegate = CallLaterDelegate
  255.     CallbackSequence = CallbackSequence
  256.     import util.callbacks
  257.     c = func
  258.     while isinstance(c, CallLater):
  259.         c = c.cb
  260.     if isinstance(c, CallbackSequence):
  261.         c = c.__call__
  262.     
  263.     if hasattr(c, 'im_func'):
  264.         code = c.im_func.func_code
  265.         nargs = code.co_argcount - 1
  266.         codeflags = code.co_flags
  267.     elif hasattr(c, 'func_code'):
  268.         code = c.func_code
  269.         nargs = code.co_argcount
  270.         codeflags = code.co_flags
  271.     else:
  272.         code = None
  273.         codeflags = 0
  274.         nargs = len(args)
  275.     hasargs = codeflags & CO_VARARGS
  276.     haskwargs = codeflags & CO_VARKEYWORDS
  277.     if haskwargs:
  278.         args = []
  279.         msg = 'callany given a kwarg function (%r): no arguments will be passed!' % funcinfo(c)
  280.         warnings.warn(msg)
  281.         if getattr(sys, 'DEV', False):
  282.             raise AssertionError(msg)
  283.         
  284.     
  285.     if not hasargs:
  286.         args = list(args)[:nargs]
  287.         args += [
  288.             None] * (nargs - len(args))
  289.     
  290.     return func(*args)
  291.  
  292.  
  293. def pythonize(s, lower = True):
  294.     if not isinstance(s, basestring):
  295.         raise TypeError, 'Only string/unicode types can be pythonized!'
  296.     
  297.     allowed = string.letters + string.digits + '_'
  298.     s = str(s).strip()
  299.     if s.startswith('__') and s.endswith('__'):
  300.         s = s[2:-2]
  301.     
  302.     s = None if s[0] in string.digits else '' + s
  303.     s = None if keyword.iskeyword(s) else '' + s
  304.     new_s = ''
  305.     for ch in s:
  306.         None += new_s if ch in allowed else '_'
  307.     
  308.     if lower:
  309.         new_s = new_s.lower()
  310.     
  311.     return new_s
  312.  
  313. attached_functions = { }
  314.  
  315. def dyn_dispatch(obj, func_name, *args, **kwargs):
  316.     func_name = pythonize(str(func_name))
  317.     if not hasattr(obj, func_name):
  318.         fn = sys._getframe(1).f_code.co_filename
  319.         d = dict(name = func_name)
  320.         d.update(kwargs)
  321.         code = str(obj.func_templ % d)
  322.         f = open(fn, 'a')
  323.         f.write(code)
  324.         f.close()
  325.         newcode = ''
  326.         code = code.replace('\n    ', '\n')
  327.         exec code
  328.         attach_method(obj, locals()[func_name])
  329.         l = attached_functions.setdefault(obj.__class__, [])
  330.         l.append(func_name)
  331.     
  332.     if func_name in attached_functions.setdefault(obj.__class__, []):
  333.         args = [
  334.             obj] + list(args)
  335.     
  336.     return getattr(obj, func_name)(*args, **kwargs)
  337.  
  338.  
  339. class CallTemplate(string.Template):
  340.     
  341.     def __init__(self, templ):
  342.         string.Template.__init__(self, templ)
  343.         self.placeholders = [ m[1] for m in re.findall(self.pattern, self.template) ]
  344.  
  345.     
  346.     def __call__(self, *args, **kws):
  347.         return self.substitute(**primitives.dictadd(zip(self.placeholders, args), kws))
  348.  
  349.  
  350. _profilers_enabled = False
  351.  
  352. def set_profilers_enabled(val):
  353.     global _profilers_enabled
  354.     _profilers_enabled = val
  355.  
  356.  
  357. def use_profiler(target, callable):
  358.     target.profiler = EnableDisableProfiler()
  359.     
  360.     def cb():
  361.         if not _profilers_enabled:
  362.             target.profiler.disable()
  363.         
  364.         callable()
  365.  
  366.     if sys.platform == 'win32':
  367.         SEHGuard = SEHGuard
  368.         import wx
  369.     else:
  370.         
  371.         SEHGuard = lambda c: c()
  372.     (None, target.profiler.runcall)((lambda : SEHGuard(cb)))
  373.  
  374.  
  375. def all_profilers():
  376.     return dict((lambda .0: for thread in .0:
  377. if hasattr(thread, 'profiler'):
  378. (thread, thread.profiler)continue)(threading.enumerate()))
  379.  
  380.  
  381. def get_profile_report(profiler):
  382.     Stats = Stats
  383.     import pstats
  384.     StringIO = StringIO
  385.     import cStringIO
  386.     io = StringIO()
  387.     stats = Stats(profiler, stream = io)
  388.     io.write('\nby cumulative time:\n\n')
  389.     stats.sort_stats('cumulative').print_stats(25)
  390.     io.write('\nby number of calls:\n\n')
  391.     stats.sort_stats('time').print_stats(25)
  392.     return io.getvalue()
  393.  
  394. from cProfile import Profile
  395. Profile.report = get_profile_report
  396.  
  397. def profilereport():
  398.     s = []
  399.     for thread, profiler in all_profilers().iteritems():
  400.         s.extend([
  401.             repr(thread),
  402.             profiler.report()])
  403.     
  404.     return '\n'.join(s)
  405.  
  406.  
  407. class Memoize(object):
  408.     __slots__ = [
  409.         'func',
  410.         'cache']
  411.     
  412.     def __init__(self, func):
  413.         self.func = func
  414.         self.cache = { }
  415.  
  416.     
  417.     def __repr__(self):
  418.         return '<Memoize for %r (%d items)>' % (funcinfo(self.func), len(self.cache))
  419.  
  420.     
  421.     def __call__(self, *args, **kwargs):
  422.         key = (args, tuple(kwargs.items()))
  423.         cache = self.cache
  424.         
  425.         try:
  426.             return cache[key]
  427.         except KeyError:
  428.             return cache.setdefault(key, self.func(*args, **kwargs))
  429.  
  430.  
  431.  
  432. memoize = Memoize
  433.  
  434. memoizedprop = lambda getter: property(memoize(getter))
  435.  
  436. def print_timing(num_runs = 1):
  437.     
  438.     def wrapper1(func):
  439.         
  440.         def wrapper(*arg, **kwargs):
  441.             t1 = time.clock()
  442.             for i in range(num_runs):
  443.                 res = func(*arg, **kwargs)
  444.             
  445.             t2 = time.clock()
  446.             print '%s took %0.3fms.' % (func.func_name, (t2 - t1) * 1000 / float(num_runs))
  447.             return res
  448.  
  449.         return wrapper
  450.  
  451.     return wrapper1
  452.  
  453.  
  454. class i(int):
  455.     
  456.     def __iter__(self):
  457.         return iter(xrange(self))
  458.  
  459.  
  460.  
  461. def baseclasses(cls):
  462.     if not hasattr(cls, '__bases__'):
  463.         raise TypeError('%r does not have __bases__' % cls)
  464.     
  465.     bases = []
  466.     for c in cls.__bases__:
  467.         bases.append(c)
  468.         bases.extend(baseclasses(c))
  469.     
  470.     return bases
  471.  
  472.  
  473. def reload_(obj):
  474.     for klass in reversed(obj.__class__.__mro__):
  475.         if klass not in __builtins__:
  476.             reload(sys.modules[klass.__module__])
  477.             continue
  478.     
  479.     return reload2_(obj)
  480.  
  481.  
  482. def reload2_(obj):
  483.     m = sys.modules[obj.__class__.__module__]
  484.     m = reload(m)
  485.     cl = getattr(m, obj.__class__.__name__)
  486.     obj.__class__ = cl
  487.     return sys.modules[obj.__class__.__module__]
  488.  
  489.  
  490. def bitflags_enabled(map, flags):
  491.     bits = _[1]
  492.     return _[2]
  493.  
  494.  
  495. def import_module(modulePath):
  496.     
  497.     try:
  498.         aMod = sys.modules[modulePath]
  499.         if not isinstance(aMod, types.ModuleType):
  500.             raise KeyError
  501.     except KeyError:
  502.         aMod = __import__(modulePath, globals(), locals(), [
  503.             ''])
  504.         sys.modules[modulePath] = aMod
  505.  
  506.     return aMod
  507.  
  508.  
  509. def import_function(fullFuncName):
  510.     if not isinstance(fullFuncName, basestring):
  511.         raise TypeError('import_function needs a string, you gave a %s' % type(fullFuncName))
  512.     
  513.     lastDot = fullFuncName.rfind(u'.')
  514.     funcName = fullFuncName[lastDot + 1:]
  515.     modPath = fullFuncName[:lastDot]
  516.     aMod = import_module(modPath)
  517.     aFunc = getattr(aMod, funcName)
  518.     return aFunc
  519.  
  520.  
  521. def base_classes(clazz):
  522.     classes = []
  523.     for cl in clazz.__bases__:
  524.         classes += [
  525.             cl] + base_classes(cl)
  526.     
  527.     return list(set(classes))
  528.  
  529. base_classes = memoize(base_classes)
  530.  
  531. def wrapfunc(obj, name, processor, avoid_doublewrap = True):
  532.     call = getattr(obj, name)
  533.     if avoid_doublewrap and getattr(call, 'processor', None) is processor:
  534.         return None
  535.     
  536.     original_callable = getattr(call, 'im_func', call)
  537.     
  538.     def wrappedfunc(*args, **kwargs):
  539.         return processor(original_callable, *args, **kwargs)
  540.  
  541.     wrappedfunc.original = call
  542.     wrappedfunc.processor = processor
  543.     wrappedfunc.__name__ = getattr(call, '__name__', name)
  544.     if inspect.isclass(obj):
  545.         if hasattr(call, 'im_self'):
  546.             if call.im_self:
  547.                 wrappedfunc = classmethod(wrappedfunc)
  548.             
  549.         else:
  550.             wrappedfunc = staticmethod(wrappedfunc)
  551.     
  552.     setattr(obj, name, wrappedfunc)
  553.  
  554.  
  555. def unwrapfunc(obj, name):
  556.     setattr(obj, name, getattr(obj, name).original)
  557.  
  558.  
  559. def tracing_processor(original_callable, *args, **kwargs):
  560.     r_name = getattr(original_callable, '__name__', '<unknown>')
  561.     r_args = [ (primitives.try_this,)((lambda : repr(a)), '<%s at %s>' % (type(a), id(a))) for None in args ]
  562.     []([ '%s-%r' % x for x in kwargs.iteritems() ])
  563.     print '-> %s(%s)' % (r_name, ', '.join(r_args))
  564.     return original_callable(*args, **kwargs)
  565.  
  566.  
  567. def add_tracing(class_object, method_name):
  568.     wrapfunc(class_object, method_name, tracing_processor)
  569.  
  570.  
  571. def trace(clz):
  572.     for meth, v in inspect.getmembers(clz, inspect.ismethod):
  573.         if not meth.startswith('__'):
  574.             add_tracing(clz, meth)
  575.             continue
  576.     
  577.  
  578.  
  579. def typecounts(contains = None, objs = None):
  580.     import gc
  581.     if objs is None:
  582.         objs = gc.get_objects()
  583.     
  584.     counts = defaultdict(int)
  585.     for obj in objs:
  586.         counts[type(obj).__name__] += 1
  587.     
  588.     if contains is not None:
  589.         
  590.         contains = lambda s, ss = contains: s[0].find(ss) != -1
  591.     
  592.     return filter(contains, sorted(counts.iteritems(), key = (lambda a: a[1]), reverse = True))
  593.  
  594.  
  595. def funcinfo(func):
  596.     if not hasattr(func, 'func_code'):
  597.         return repr(func)
  598.     
  599.     name = getattr(func, '__name__', getattr(getattr(func, '__class__', None), '__name__', '<UNKNOWN OBJECT>'))
  600.     c = func.func_code
  601.     filename = c.co_filename
  602.     if not isinstance(filename, str):
  603.         filename = '??'
  604.     else:
  605.         
  606.         try:
  607.             filepath = path(c.co_filename)
  608.             if filepath.name == '__init__.py':
  609.                 filename = filepath.parent.name + '/' + filepath.name
  610.             else:
  611.                 filename = filepath.name
  612.         except Exception:
  613.             print_exc()
  614.  
  615.     return '<%s (%s:%s)>' % (name, filename, c.co_firstlineno)
  616.  
  617.  
  618. def leakfinder():
  619.     import wx
  620.     pprint = pprint
  621.     import pprint
  622.     typecounts = typecounts
  623.     import util
  624.     import gc
  625.     f = wx.Frame(None, pos = (30, 30), style = wx.DEFAULT_FRAME_STYLE | wx.FRAME_TOOL_WINDOW | wx.STAY_ON_TOP)
  626.     b = wx.Button(f, -1, 'memory stats')
  627.     b2 = wx.Button(f, -1, 'all functions')
  628.     b3 = wx.Button(f, -1, 'all unnamed lambdas')
  629.     sz = f.Sizer = wx.BoxSizer(wx.VERTICAL)
  630.     sz.AddMany([
  631.         b,
  632.         b2,
  633.         b3])
  634.     f.stats = { }
  635.     
  636.     def onstats(e):
  637.         new = typecounts()
  638.         news = dict(new)
  639.         for cname in news.keys():
  640.             if cname in f.stats:
  641.                 diff = news[cname] - f.stats[cname][0]
  642.                 f.stats[cname] = (news[cname], diff)
  643.                 continue
  644.             f.stats[cname] = (news[cname], 0)
  645.         
  646.         print '****' * 10
  647.         pprint(sorted(f.stats.iteritems(), key = (lambda a: a[1])))
  648.  
  649.     
  650.     def on2(e, filterName = ((None, None, None), None)):
  651.         funcs = _[1]
  652.         counts = defaultdict(int)
  653.         for f in funcs:
  654.             pass
  655.         
  656.         print '((Filename, Line Number), Count)'
  657.         pprint(sorted(list(counts.iteritems()), key = (lambda i: i[1])))
  658.  
  659.     b.Bind(wx.EVT_BUTTON, onstats)
  660.     b2.Bind(wx.EVT_BUTTON, on2)
  661.     b3.Bind((wx.EVT_BUTTON,), (lambda e: on2(e, '<lambda>')))
  662.     f.Sizer.Layout()
  663.     f.Fit()
  664.     f.Show()
  665.  
  666.  
  667. def counts(seq, groupby):
  668.     counts = defaultdict(int)
  669.     for obj in seq:
  670.         counts[groupby(obj)] += 1
  671.     
  672.     return sorted((lambda .0: for val, count in .0:
  673. (count, val))(counts.iteritems()), reverse = True)
  674.  
  675.  
  676. class InstanceTracker(object):
  677.     
  678.     def track(self):
  679.         
  680.         try:
  681.             _instances = self.__class__._instances
  682.         except AttributeError:
  683.             self.__class__._instances = [
  684.                 ref(self)]
  685.  
  686.         for wref in _instances:
  687.             if wref() is self:
  688.                 break
  689.                 continue
  690.         
  691.  
  692.     
  693.     def all(cls):
  694.         objs = []
  695.         
  696.         try:
  697.             wrefs = cls._instances
  698.         except AttributeError:
  699.             return []
  700.  
  701.         import wx
  702.         for wref in wrefs[:]:
  703.             obj = wref()
  704.             if obj is not None:
  705.                 if wx.IsDestroyed(obj):
  706.                     wrefs.remove(wref)
  707.                 else:
  708.                     objs.append(obj)
  709.             wx.IsDestroyed(obj)
  710.         
  711.         return objs
  712.  
  713.     all = classmethod(all)
  714.     
  715.     def CallAll(cls, func, *args, **kwargs):
  716.         import wx
  717.         
  718.         try:
  719.             instances = cls._instances
  720.         except AttributeError:
  721.             return None
  722.  
  723.         removeList = []
  724.         for wref in instances:
  725.             obj = wref()
  726.             if obj is not None and not wx.IsDestroyed(obj):
  727.                 
  728.                 try:
  729.                     func(obj, *args, **kwargs)
  730.                 except TypeError:
  731.                     print type(obj), repr(obj)
  732.                     raise 
  733.                 except:
  734.                     None<EXCEPTION MATCH>TypeError
  735.                 
  736.  
  737.             None<EXCEPTION MATCH>TypeError
  738.             removeList.append(wref)
  739.         
  740.         for wref in removeList:
  741.             
  742.             try:
  743.                 instances.remove(wref)
  744.             continue
  745.             except ValueError:
  746.                 continue
  747.             
  748.  
  749.         
  750.  
  751.     CallAll = classmethod(CallAll)
  752.  
  753.  
  754. class DeadObjectError(AttributeError):
  755.     pass
  756.  
  757.  
  758. class DeadObject(object):
  759.     reprStr = 'Placeholder for DELETED %s object! Please unhook all callbacks, observers, and event handlers PROPERLY.'
  760.     attrStr = 'Attribute access no longer allowed - This object has signaled that it is no longer valid!'
  761.     
  762.     def __repr__(self):
  763.         if not hasattr(self, '_name'):
  764.             self._name = '[unknown]'
  765.         
  766.         return self.reprStr % self._name
  767.  
  768.     
  769.     def __getattr__(self, *args):
  770.         if not hasattr(self, '_name'):
  771.             self._name = '[unknown]'
  772.         
  773.         raise DeadObjectError(self.attrStr % self._name)
  774.  
  775.     
  776.     def __nonzero__(self):
  777.         return 0
  778.  
  779.  
  780.  
  781. def gc_diagnostics(stream = None):
  782.     import gc
  783.     import sys
  784.     import linecache as linecache
  785.     import locale as locale
  786.     itemgetter = itemgetter
  787.     import operator
  788.     ifilterfalse = ifilterfalse
  789.     imap = imap
  790.     import itertools
  791.     getrefcount = sys.getrefcount
  792.     if stream is None:
  793.         stream = sys.stdout
  794.     
  795.     linecache.clearcache()
  796.     gc.collect()
  797.     
  798.     def w(s):
  799.         stream.write(s + '\n')
  800.  
  801.     filter_objects = ((), '')
  802.     filter_types = (type,)
  803.     objs = _[1]
  804.     itemgetter0 = itemgetter(0)
  805.     itemgetter1 = itemgetter(1)
  806.     objs.sort(key = itemgetter0)
  807.     num_objs = len(objs)
  808.     w('%d objects' % num_objs)
  809.     N = 600
  810.     notallowed = (basestring,)
  811.     import __builtin__ as __builtin__
  812.     blacklist = set()
  813.     oldlen = 0
  814.     modlen = len(sys.modules)
  815.     while modlen != oldlen:
  816.         blacklist |= set((lambda .0: for m in .0:
  817. if m:
  818. id(m.__dict__)continue)(sys.modules.itervalues()))
  819.         for m in sys.modules.values():
  820.             if m and hasattr(m, '__docfilter__'):
  821.                 blacklist.add(id(m.__docfilter__._globals))
  822.                 continue
  823.             []
  824.         
  825.         oldlen = modlen
  826.         modlen = len(sys.modules)
  827.         continue
  828.         []
  829.     blacklist.add(id(__builtin__))
  830.     blacklist.add(id(__builtin__.__dict__))
  831.     blacklist.add(id(sys.modules))
  832.     blacklist.add(id(locale.locale_alias))
  833.     if sys.modules.get('stringprep', None) is not None:
  834.         import stringprep
  835.         blacklist.add(id(stringprep.b3_exceptions))
  836.     
  837.     blacklist.add(id(objs))
  838.     
  839.     def blacklisted(z):
  840.         if not isinstance(z, notallowed) and id(z) in blacklist:
  841.             pass
  842.         return z is blacklist
  843.  
  844.     
  845.     def blacklisted_1(z):
  846.         z = z[-1]
  847.         return blacklisted(z)
  848.  
  849.     
  850.     def large_sequence(z):
  851.         
  852.         try:
  853.             if len(z) > 300:
  854.                 pass
  855.             return not blacklisted(z)
  856.         except:
  857.             pass
  858.  
  859.  
  860.     
  861.     def saferepr(obj):
  862.         
  863.         try:
  864.             return repr(obj)
  865.         except Exception:
  866.             e = None
  867.             
  868.             try:
  869.                 return '<%s>' % type(obj).__name__
  870.             return '<??>'
  871.  
  872.  
  873.  
  874.     num_most_reffed = min(int(num_objs * 0.05), 20)
  875.     most_reffed = ifilterfalse(blacklisted_1, reversed(objs))
  876.     w('\n\n')
  877.     w('*** top %d referenced objects' % num_most_reffed)
  878.     w('sys.getrefcount(obj), repr(obj)[:1000]')
  879.     for nil in xrange(num_most_reffed):
  880.         
  881.         try:
  882.             (rcount, obj) = most_reffed.next()
  883.         except StopIteration:
  884.             (((None, None),),)
  885.             (((None, None),),)
  886.             break
  887.         except:
  888.             (((None, None),),)
  889.  
  890.         w('%d %d: %s' % (rcount, id(obj), saferepr(obj)[:1000]))
  891.     
  892.     w('\n\n')
  893.     w('*** objects with __len__ more than %d' % N)
  894.     w('__len__(obj), repr(obj)[:1000]')
  895.     large_objs = [](_[2], key = itemgetter0, reverse = True)
  896.     for count, _id, s in large_objs:
  897.         if _id != id(objs):
  898.             w('count %d id %d: %s' % (count, _id, s))
  899.             continue
  900.         []
  901.     
  902.     w('\n\n')
  903.     _typecounts = typecounts(objs = imap(itemgetter1, objs))
  904.     num_types = 20
  905.     w('*** top %d instantiated types' % num_types)
  906.     builtin_names = set(__builtins__.keys())
  907.     tc_iter = (sorted, ifilterfalse)((lambda _x: builtin_names.__contains__(itemgetter0(_x))), _typecounts)
  908.     for nil in range(num_types):
  909.         
  910.         try:
  911.             (tname, tcount) = tc_iter.next()
  912.         except StopIteration:
  913.             (((None, None),),)
  914.             (((None, None),),)
  915.             break
  916.         except:
  917.             (((None, None),),)
  918.  
  919.         w('%d: %r' % (tcount, tname))
  920.     
  921.     funcinfos = defaultdict(int)
  922.     for refcount, obj in objs:
  923.         if callable(obj):
  924.             
  925.             try:
  926.                 finfo = funcinfo(obj)
  927.             except:
  928.                 (((None, None),),)
  929.                 continue
  930.  
  931.             funcinfos[finfo] += refcount
  932.             continue
  933.         (((None, None),),)
  934.     
  935.     num_infos = min(len(funcinfos), 20)
  936.     funcinfos = funcinfos.items()
  937.     funcinfos.sort(key = itemgetter1, reverse = True)
  938.     w('\n\n')
  939.     w('*** %d most referenced callables' % num_infos)
  940.     for i in range(num_infos):
  941.         (finfo, frcount) = funcinfos[i]
  942.         w('%d: %r' % (frcount, finfo))
  943.     
  944.     
  945.     try:
  946.         import wx
  947.     except ImportError:
  948.         pass
  949.  
  950.     w('\n\n*** top level windows')
  951.     for tlw in wx.GetTopLevelWindows():
  952.         w(saferepr(tlw))
  953.     
  954.     w('\n\n*** gc.garbage')
  955.     if not gc.garbage:
  956.         w('(none)')
  957.     else:
  958.         for obj in gc.garbage:
  959.             w(saferepr(obj))
  960.         
  961.  
  962. import cProfile
  963. import _lsprof
  964.  
  965. class EnableDisableProfiler(cProfile.Profile):
  966.     
  967.     def __init__(self, *a, **k):
  968.         self.enabled = False
  969.         _lsprof.Profiler.__init__(self, *a, **k)
  970.  
  971.     
  972.     def enable(self):
  973.         self.enabled = True
  974.         return _lsprof.Profiler.enable(self)
  975.  
  976.     
  977.     def disable(self):
  978.         self.enabled = False
  979.         return _lsprof.Profiler.disable(self)
  980.  
  981.  
  982. if __name__ == '__main__':
  983.     from pprint import pprint
  984.     pprint(typecounts('Graphics'))
  985.  
  986.